﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Globalization;
using System.ComponentModel;
using System.Text.RegularExpressions;

namespace SetListManager.Models
{
    // Custom timespanmodelbinder -- allows us to use the timepsan picker drop-down.  
    // Code from http://stackoverflow.com/questions/3832176/generic-timespan-binding-in-asp-net-mvc-2
    
    public sealed class MyTimeSpanModelBinder : DefaultModelBinder
    {
        private const DateTimeStyles _dateTimeStyles = DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeLocal | DateTimeStyles.NoCurrentDateDefault;

        protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
        {
            var form = controllerContext.HttpContext.Request.Form;

            if (propertyDescriptor.PropertyType.Equals(typeof(TimeSpan?)) || propertyDescriptor.PropertyType.Equals(typeof(TimeSpan)))
            {
                var text = form[propertyDescriptor.Name];
                TimeSpan time;
                if (TryParseTime(text, out time))
                {
                    SetProperty(controllerContext, bindingContext, propertyDescriptor, time);
                    return;
                }
            }

            // Either a different type, or we couldn't parse the string.
            base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
        }

        public static bool TryParseTime(string text, out TimeSpan time)
        {
            if (text == null)
                throw new ArgumentNullException("text");

            var formats = new[] {
            "HH:mm", "HH.mm", "HHmm", "HH,mm", "HH",
            "H:mm", "H.mm", "H,mm",
            "hh:mmtt", "hh.mmtt", "hhmmtt", "hh,mmtt", "hhtt",
            "h:mmtt", "h.mmtt", "hmmtt", "h,mmtt", "htt"
        };

            text = Regex.Replace(text, "([^0-9]|^)([0-9])([0-9]{2})([^0-9]|$)", "$1$2:$3$4");
            text = Regex.Replace(text, "^[0-9]$", "0$0");

            foreach (var format in formats)
            {
                DateTime value;
                if (DateTime.TryParseExact(text, format, CultureInfo.InvariantCulture, _dateTimeStyles, out value))
                {
                    time = value.TimeOfDay;
                    return true;
                }
            }
            time = TimeSpan.Zero;
            return false;
        }
    }
}